import { ViteDevServer } from 'vite'
import esbuild from 'esbuild'
import electron from 'electron'
import type { AddressInfo } from 'net'
import { spawn } from 'child_process'

export const devPlugin = () => {
  return {
    name: 'vite-plugin-electron',
    configureServer(server: ViteDevServer) {
      // 开发服务器启动时的钩子
      console.log('开发服务器启动中...')

      // 打包编译electron文件
      esbuild.buildSync({
        entryPoints: ['./src/main/mainEntry.ts'],
        bundle: true,
        platform: 'node',
        outfile: './dist/mainEntry.js',
        external: ['electron']
      })

      // 监听http服务成功启动
      if (!server.httpServer) return console.log('服务异常')

      server.httpServer.once('listening', () => {
        console.log('开发服务器启动成功...')
        if (!server.httpServer) return console.log('服务异常')

        const addressInfo = server.httpServer.address() as AddressInfo
        const httpAddress = `http://${addressInfo?.address}:${addressInfo.port}`

        const electronProcess = spawn(electron.toString(), ['./dist/mainEntry.js', httpAddress], {
          cwd: process.cwd(),
          stdio: 'inherit'
        })

        electronProcess.on('close', async () => {
          await server.close()
          process.exit()
        })
      })
    }
  }
}

export const getReplacer = () => {
  const externalModels = [
    'os',
    'fs',
    'path',
    'events',
    'child_process',
    'crypto',
    'http',
    'buffer',
    'url',
    'better-sqlite3',
    'knex'
  ]
  const result: any = {}

  for (const itemModel of externalModels) {
    result[itemModel] = () => ({
      find: new RegExp(`^${itemModel}$`),
      code: `const ${itemModel} = require('${itemModel}');export { ${itemModel} as default }`
    })
  }

  result.electron = () => {
    const electronModules = ['clipboard', 'ipcRenderer', 'nativeImage', 'shell', 'webFrame'].join(
      ','
    )
    return {
      find: /^electron$/,
      code: `const {${electronModules}} = require('electron');export {${electronModules}}`
    }
  }
  return result
}
